/*
 * DerbyDB.java
 *
 * Created on June 10, 2007, 9:36 PM
 *
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.fpdev.core.data;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import org.fpdev.core.FPEngine;
import org.fpdev.core.DataPackage;
import org.fpdev.core.SysProps;
import org.fpdev.util.FPUtil;

/**
 *
 * @author demory
 */
public class LegacyDerbyDB extends LegacyDB {

  /** Creates a new instance of DerbyDB */
  public LegacyDerbyDB(FPEngine engine, DataPackage pkg) {
    this(engine, pkg, null);
  }

  public LegacyDerbyDB(FPEngine engine, DataPackage pkg, ZipFile zip) {
    super(engine, pkg, "", "", zip);
  }

  public void init() throws SQLException {
    try {
      conn_ = DriverManager.getConnection("jdbc:derby:" + engine_.getProperty("derbyHome") + dataPkg_.getName(), "user1", "user1");
      System.out.println("Connected to existing derby database " + dataPkg_.getName());
      s_ = conn_.createStatement();
      initialized_ = true;
    } catch (SQLException e) {
      initialized_ = createDB();
    }
  }
  
  private boolean createDB() {
    try {
      System.out.println("Derby database not found, creating...");
      String dir = engine_.getProperty(SysProps.DERBY_HOME) + dataPkg_.getName();
      System.out.println("dir: "+dir);
      conn_ = DriverManager.getConnection("jdbc:derby:" + dir + ";create=true", "user1", "user1");
      System.out.println("Created and connected to Derby database " + dataPkg_.getName());
      s_ = conn_.createStatement();
      createBaseNetTables();
      System.out.println("Created tables");
      return true;
    } catch (SQLException ex) {
      System.out.println("Error creating Derby database/tables");
      ex.printStackTrace();
      return false;
    }
    
  }

  public void close() {
    try {

      s_.close();
      System.out.println("Closed result set and statement");

      boolean gotSQLExc = false;

      try {
        DriverManager.getConnection("jdbc:derby:;shutdown=true");
      } catch (SQLException se) {
        gotSQLExc = true;
      }

      if (!gotSQLExc) {
        System.out.println("Database did not shut down normally");
      } else {
        System.out.println("Database shut down normally");
      }
    } catch (Throwable e) {
      System.out.println("exception thrown:");
      e.printStackTrace();
    }
  }

  public int getRDBMS() {
    return DB_DERBY;
  }

  public String jdbcClassname() {
    return "org.apache.derby.jdbc.EmbeddedDriver";
  }

  public void dumpToZip(ZipOutputStream zos) {
    String dbHome = engine_.getProperty("derbyHome");
    FPUtil.zipDir(dbHome + dataPkg_.getName(), zos, dbHome.length(), "derby_");
  }

  public void readFromZip(ZipFile zipFile) {
    System.out.println("Reading from zip");
    try {
      Enumeration entries = zipFile.entries();

      String dir = engine_.getProperty("derbyHome");
      while (entries.hasMoreElements()) {
        ZipEntry entry = (ZipEntry) entries.nextElement();
        String eName = entry.getName();
        if (!eName.startsWith("derby_")) {
          continue;
        }
        eName = eName.substring(6);
        eName = FPUtil.fixFilename(eName);

        if (entry.isDirectory()) {
          // Assume directories are stored parents first then children.
          System.err.println("Extracting directory: " + entry.getName());
          (new File(dir + eName)).mkdir();
          continue;
        }

        //System.err.println("Extracting file: " + eName);
        (new File(dir + eName).getParentFile()).mkdirs();
        FPUtil.copyInputStream(zipFile.getInputStream(entry),
                new BufferedOutputStream(new FileOutputStream(dir + eName)));

      }

      zipFile.close();
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }

  public void delete() {
    close();
    FPUtil.deleteDirectory(engine_.getProperty("5pHome") + "derby" + File.separator + dataPkg_.getName());
  }
}
